#include <stdio.h>
#include <pthread.h>
#include <sys/time.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <string.h>
#include <stdlib.h>
//#include "gprmc.h"
//#include "lvx_file.h"
//#include "time_info.h"
typedef unsigned char u8;
int flag_exit_gps = 0;

u8 filename[30]={0};

char path[100] = {0};
struct package{
	u8 header;
	u8 kind;
	u8 length_07;
	u8 length_815;
	u8 length_1623;
	u8 length_2431;
	u8 *gprmc;
	u8 tail1;
	u8 tail2;
};
void substring(char *des,char *str,int n,int index){
	char *p = des;
	char *q = str;
	int len = strlen(str);
	*(p++) = *(q);
	if(n>len) n = len-index;
	if(index<0) index=0;
	if(index>len) return ;
	q += index;
	while(n--) *(p++) = *(q++);
	*(p++) = '\0';
	
}

void BCC(u8 *data,u8 *res){
	int len = strlen((char*)data);
	u8 checknum = '\0';
	int i=1;
	for(i=1;i<len-1;i++){
		checknum = checknum ^ data[i];
	}
	
	sprintf((char*)res,"%02x",checknum&0x00ff);
	
} 
int getMsTime(){
	struct timeval tv;
        gettimeofday(&tv,NULL);
        long ms = tv.tv_usec/1000;
	return ms;
}


void lenToHex(char *des,long len){
   
    des[0] = len&0x00ff;
    des[1] = (len>>8)&0x00ff;
    des[2] = (len>>16)&0x00ff;
    des[3] = (len>>24)&0x00ff;
    
}

void lock_set(int fd, int type)
{
    struct flock lock;
    lock.l_whence = SEEK_SET;//璧嬪€糽ock缁撴瀯浣?
    lock.l_start = 0;
    lock.l_len =0;
    while(1){
        lock.l_type = type;
        /*鏍规嵁涓嶅悓鐨則ype鍊肩粰鏂囦欢涓婇攣鎴栬В閿?/
        if((fcntl(fd, F_SETLK, &lock)) == 0){
            if( lock.l_type == F_RDLCK )
            printf("read lock set by %d\n",getpid());
            else if( lock.l_type == F_WRLCK )
            printf("write lock set by %d\n",getpid());
            else if( lock.l_type == F_UNLCK )
            printf("release lock by %d\n",getpid());
            return;
        }
        /*鍒ゆ柇鏂囦欢鏄惁鍙互涓婇攣*/
        fcntl(fd, F_GETLK,&lock);
        /*鍒ゆ柇鏂囦欢涓嶈兘涓婇攣鐨勫師鍥?/
        if(lock.l_type != F_UNLCK){
            /*璇ユ枃浠跺凡鏈夎鍙栭攣
            if( lock.l_type == F_RDLCK )
            printf("read lock already set by %d\n",lock.l_pid);
            */
            /*璇ユ枃浠跺凡鏈夊啓鍏ラ攣*/
            if( lock.l_type == F_WRLCK )
                printf("write lock already set by %d\n",lock.l_pid);
            //getchar();
        //}
    }
}

FILE * g_fp = NULL;

void write_to_lvx(unsigned char * data_in,int len,int need_flush)
{
    fwrite(data_in,1,len,g_fp);	
	if(need_flush)
	{
		fflush(g_fp);
	}
}

char str_gps_utc[32];
int flag_gps = 0;
extern volatile int rising_flag;
char str_rise_time[64];

void savePackage_pps(char * str_in)
{

    char buff_write[128] = {0};
    int len_str = strlen(str_in);
    char * ptr_data = buff_write;

    char sum[4];
	
	printf("pps save:%s\r\n",str_in);

    buff_write[0] = 0x7b;
    buff_write[1] = 0x04;
    buff_write[2] = len_str + 3;
    buff_write[3] = 0x00;
    buff_write[4] = 0x00;
    buff_write[5] = 0x00;

    memcpy(buff_write+6,str_in,len_str);   

    BCC(str_in,sum);

    buff_write[6+len_str] = '*';
    buff_write[7+len_str] = sum[0];
    buff_write[8+len_str] = sum[1];

    ptr_data += (len_str + 9);
    
    *ptr_data = 0x0d;
    ptr_data++;
    *ptr_data = 0x0a;
    //pthread_mutex_lock(&mutex_file_wr);

    write_to_lvx((unsigned char *)buff_write, len_str+9,1);

    //pthread_mutex_unlock(&mutex_file_wr);

    rising_flag = 0;
    
}


void *saveToPackage(void *arg){
	//int ms = getMsTime();	

	char buff_pps[64];
	
	u8 *GPRMC = (u8 *)arg;
        int gprmc_len = strlen((char*)GPRMC);
        memset(str_gps_utc,0,32);
        char * dot_p = strchr((char *)GPRMC,'.');
        if(dot_p == NULL)
        {
            return NULL;
        }
    memcpy(str_gps_utc,dot_p-6,9);
        printf("utc time:%s\r\n",str_gps_utc);
        sprintf(str_rise_time,"%s","2.089");
    sprintf(buff_pps,"$,%s,%s",str_gps_utc,str_rise_time);

    savePackage_pps(buff_pps);
    //flag_gps = 1;
	//printf("GPRMC %s\n",GPRMC);
	//char cms[12] = {0};

	char *temp_gprmc = (char *)malloc(gprmc_len*sizeof(u8)) ;
	memset(temp_gprmc,0,gprmc_len);
	char *s;
	char check[4];

	if(strchr(GPRMC,'*'))
	{
	    substring(temp_gprmc,(char*)GPRMC,gprmc_len-10,7);
	}
	else
	{
	    substring(temp_gprmc,(char*)GPRMC,gprmc_len-7,7);
	}	

	char runtime_str[24] = "2.034";
	g_run_duration->get_delta_str(runtime_str);

	
	
	//sprintf(cms,",%03d*",ms);
	temp_gprmc = (char *)realloc(temp_gprmc,(strlen(temp_gprmc)+strlen(runtime_str)+8)*sizeof(u8));
	//strcat(temp_gprmc,runtime_str);
        sprintf(temp_gprmc,"%s,%s",temp_gprmc,runtime_str);
	printf("%s\n",temp_gprmc);
	
	BCC((u8*)temp_gprmc,(u8*)check);
	
	//strcat(temp_gprmc,check);
        sprintf(temp_gprmc,"%s*%s",temp_gprmc,check);
	printf("%s\n bbc %s\n",temp_gprmc,check);
	
	//printf("size %d\n size %d\n ",strlen(GPRMC),strlen(temp_gprmc));
	int len = strlen(temp_gprmc);
	struct package *pk; 
	
	pk = (struct package *)malloc(sizeof(struct package));
	pk->gprmc = (u8 *)malloc(len*sizeof(u8));
	
	pk->header = 0x7B;
	pk->kind = 0x01;
	char *des = (char*)malloc(sizeof(char)*4);
	lenToHex(des,len);
	pk->length_07 = des[0];
	pk->length_815 = des[1];
	pk->length_1623 = des[2];
	pk->length_2431 = des[3];
	
	sprintf((char*)pk->gprmc,"%s",temp_gprmc);
	pk->tail1 = 0x0D;
	pk->tail2 = 0x0A;
	

	
//	FILE *fp;
//	fp = fopen(path,"ab+");
//	while(!fp){
//		usleep(30);
//		fp = fopen(path,"ab+");
//	}
        pthread_mutex_lock(&mutex_file_wr);
        write_to_lvx(&(pk->header),sizeof(pk->header),0);
        write_to_lvx(&(pk->kind),sizeof(pk->kind),0);
        write_to_lvx(&(pk->length_07),sizeof(pk->length_07),0);        
	write_to_lvx(&(pk->length_815),sizeof(pk->length_815),0);
	write_to_lvx(&(pk->length_1623),sizeof(pk->length_1623),0);
	write_to_lvx(&(pk->length_2431),sizeof(pk->length_2431),0);
	write_to_lvx(pk->gprmc,len,0);
	write_to_lvx(&(pk->tail1),sizeof(pk->tail1),0);
	write_to_lvx(&(pk->tail2),sizeof(pk->tail2),1);

        //fwrite(&(pk->header),sizeof(pk->header),1,fp);
	//fwrite(&(pk->kind),sizeof(pk->kind),1,fp);
	//fwrite(&(pk->length_07),sizeof(pk->length_07),1,fp);
	//fwrite(&(pk->length_815),sizeof(pk->length_815),1,fp);
	//fwrite(&(pk->length_1623),sizeof(pk->length_1623),1,fp);
	//fwrite(&(pk->length_2431),sizeof(pk->length_2431),1,fp);
	//fwrite(pk->gprmc,len,1,fp);
	//fwrite(&(pk->tail1),sizeof(pk->tail1),1,fp);
	//fwrite(&(pk->tail2),sizeof(pk->tail2),1,fp);
	pthread_mutex_unlock(&mutex_file_wr);
	free(temp_gprmc);
	free(pk->gprmc);
	free(pk);
	free(des);
//	fclose(fp);
	printf("write success\n");
	/*
	int fd;
    fd = open(path,O_WRONLY | O_APPEND | O_CREAT,00777);
    while(fd < 0){
        usleep(30);
        fd = open(path,O_WRONLY | O_APPEND,00777);
    }
    lock_set(fd,F_WRLCK);
    write(fd,&(pk->header),sizeof(pk->header));
    write(fd,&(pk->kind),sizeof(pk->kind));
    write(fd,&(pk->length_07),sizeof(pk->length_07));
    write(fd,&(pk->length_815),sizeof(pk->length_815));
    write(fd,&(pk->length_1623),sizeof(pk->length_1623));
    write(fd,&(pk->length_2431),sizeof(pk->length_2431));
    write(fd,pk->gprmc,len);
    write(fd,&(pk->tail1),sizeof(pk->tail1));
    write(fd,&(pk->tail2),sizeof(pk->tail2));
    lock_set(fd,F_UNLCK);
    close(fd);
	free(temp_gprmc);
	free(pk->gprmc);
	free(pk);
	free(des);
	*/
}

const char * test_str = "$GPRMC,145625.00,V,,,,,,,210322,0.0,E,N*17";

int main(int argc, char * argv[])
{
	g_fp = fopen("test_gps.txt","wb+");
	int len = strlen(test_str);
				u8 *temp_buf = (u8 *)malloc((len+1)*sizeof(u8));
			
				memcpy(temp_buf,test_str,sizeof(u8)*len);
				temp_buf[len] = '\0';
				printf("%s\n",temp_buf);
				//create pthread
				pthread_t id;
				int ret=0;
				int n=5;
				ret = pthread_create(&id,NULL,saveToPackage,(void*)temp_buf);
				printf("ret %d",ret);
				while(ret==-1&&n){
					
					perror("create pthread error");	
					usleep(100);
					printf("waiting for recreate");
					n--;	
					ret = pthread_create(&id,NULL,saveToPackage,(void*)temp_buf);	

				}

				pthread_join(id,NULL);
	                        free(temp_buf);			
	fclose(g_fp);
	g_fp = NULL;
}
